{
 "metadata": {
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.12-final"
  },
  "orig_nbformat": 2,
  "kernelspec": {
   "name": "python3",
   "display_name": "Python 3.6.12 64-bit ('Begin': conda)",
   "metadata": {
    "interpreter": {
     "hash": "5418aa4018a4a6d4e7a95d1864632b051ddd71a0141746edebf6fac21ca2c6f9"
    }
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2,
 "cells": [
  {
   "source": [
    "# C12. 图形用户界面"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "source": [
    "## 12.1 GUI例子\n",
    "\n",
    "微型文件编辑器的需求：\n",
    "-   让用户能够打开指定的文本文件\n",
    "-   让用户能够编辑文本文件\n",
    "-   让用户能够保存文本文件\n",
    "-   让用户能够退出"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "source": [
    "### 12.1.1 结构"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "I was clicked!\n"
     ]
    }
   ],
   "source": [
    "from tkinter import *\n",
    "\n",
    "def clicked():\n",
    "    print(\"I was clicked!\")\n",
    "\n",
    "top=Tk()\n",
    "btn=Button()\n",
    "btn['text'] = 'Click me!'\n",
    "btn['command'] = clicked\n",
    "btn.config(text=\"点我！\", command=clicked)\n",
    "btn = Button(text=\"!!!\", command=clicked).pack()\n",
    "mainloop()"
   ]
  },
  {
   "source": [
    "### 12.1.2 布局\n",
    "\n",
    "对控件调用方法 pack 时，将把控件放在其父控件(主控件)中。指定主控件，可以使用构造函数的第一个可选参数；如果没有指定，将把顶级主窗口作为主控件。\n",
    "\n",
    "布局管理器\n",
    "-   pack：`help(Pack.config)`\n",
    "-   grid：`help(Grid.config)`\n",
    "-   place：`help(Place.config)`\n",
    "\n",
    "建议：一个容器只使用一种布局管理器。"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "Label(text=\"I'm in the first window!\").pack()\n",
    "second = Toplevel() # Toplevel() 是另一个顶级窗口\n",
    "Label(second, text=\"I'm in the second window!\").pack()\n",
    "mainloop()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(10):\n",
    "    Button(text=i).pack()\n",
    "mainloop()    "
   ]
  },
  {
   "source": [
    "### 12.1.3 事件\n",
    "\n",
    "`help(Tk.bind)`"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "鼠标左键在容器中的位置： 27 61\n",
      "鼠标左键在容器中的位置： 98 102\n",
      "鼠标左键在容器中的位置： 135 171\n"
     ]
    }
   ],
   "source": [
    "from tkinter import *\n",
    "\n",
    "top=Tk()\n",
    "def callback(event):\n",
    "    print(\"鼠标左键在容器中的位置：\", event.x, event.y)\n",
    "\n",
    "top.bind('<Button-1>', callback)\n",
    "mainloop()"
   ]
  },
  {
   "source": [
    "### 12.1.4 程序"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 12-1：简单的 GUI 文本编辑器\n",
    "from tkinter import *\n",
    "from tkinter.scrolledtext import ScrolledText\n",
    "\n",
    "def load():\n",
    "    with open(filename.get()) as file:\n",
    "        contents.delete('1.0',END)\n",
    "        contents.insert(INSERT, file.read())\n",
    "def save():\n",
    "    with open(filename.get(),'w') as file:\n",
    "        file.write(contents.get('1.0',END))\n",
    "\n",
    "top=Tk()\n",
    "top.title('Simple Edition')\n",
    "\n",
    "contents=ScrolledText()\n",
    "contents.pack(side=BOTTOM,expand=True,fill=BOTH)\n",
    "\n",
    "filename=Entry()\n",
    "filename.pack(side=LEFT,expand=True,fill=X)\n",
    "\n",
    "Button(text='Open', command=load).pack(side=LEFT)\n",
    "Button(text='Save',command=save).pack(side=LEFT)\n",
    "\n",
    "mainloop()"
   ]
  },
  {
   "source": [
    "## 12.2 GUI 工具包\n",
    "\n",
    "大部分 GUI 工具包的基本要素都是大致相同的，因此应该先花时间来决定使用哪个包，然后再深入研究文档并且着手开始编写代码。"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "source": [
    "## 12.3 小结\n",
    "\n",
    "-   图像用户界面(GUI)：GUI 有助于让应用程序对用户更加友好\n",
    "-   Tkinter：跨平台的 Python GUI 工具包\n",
    "-   事件处理：GUI 工具包中用户触发事件执行的操作"
   ],
   "cell_type": "markdown",
   "metadata": {}
  }
 ]
}